#init在初始化对象时触发，del再删除对象钱 . str：允许某个类的对象像字符串那个可以用print打印，通过print触发
#reper在交互式环境中通过直接键入对象名触发  cell：允许某个类的对象像函数一样调用

#魔法方法重要的是它的触发方式
#new:是开空间的，new有一个返回值，给我们即将诞生的对象,new会把地址交给init方法
#init
class A:
    def __new__(cls, *args, **kwargs):
        return B
    def __init__(self):
        self.a='今天是个上分的好日子'

class B:
    def __init__(self):
        self.a=1
aa=A()
aa.a=1
#print(aa.a)#AttributeError: 'NoneType' object has no attribute 'a'
print(aa(),aa)
print(aa().a,aa.a)
###########################

class A:
    def __new__(cls):
        return super().__new__(cls)
    def __init__(self):
        self.a='今天是个上分的好日子'

class B:
    def __init__(self):
        self.a=1
aa=A()
#print(aa.a)#AttributeError: 'NoneType' object has no attribute 'a'
print(aa)
print(aa.a)
#############
#类属性和实例属性的区别
#在类定义的时候，带了self的都是实例操作，其他都是类属性
#他们之间没有任何关系


class A:
    a=2
    def __init__(self):
        self.b=3
aa=A()
print(aa.__dict__)
print(A.__dict__)
print(aa.a)
aa.a=4
print(aa.a)
print(A.__dict__)
print(aa.__dict__)


############单例模式
class A:
    def __new__(cls,*args,**kwargs):#cls表示类本身
        if not hasattr(cls,'_xihuo'):#hasattr判断括号中的对象，是否存在括号的属性名
            ob=super(A,cls)
            cls._xihuo=ob.__new__(cls,*args,**kwargs)#if条件不成立，创建对象，完成new本该完成的工作（开辟空间，传空间）
        return cls._xihuo
    # def __init__(self,a):
    #     self.a='看今天吗'
class B(A):
    def __init__(self):#不准传cls
        self.a=1
v=B()
print(v)#TypeError: __init__() missing 1 required positional argument: 'cls'
s=A()
print(s)
#定制属性：说白了就是对实例中的某个属性进行秀爱，删除，获取的三操作
#只不过我们通过魔术方法来完成
#__setattr__()          getattr__()             delattr__()
#实例的时候调用setattr    获取的时候                删除的时候
# class Police:
#     def __init__(self):
#         self.name='xihuo'
#
#     def __setattr__(self, key, value):
#         if key=='name':
#             print('现在修改的值是%s'%key)
#             self.__dict__[key]=value
#             print(key)
#             print(value)
#     def get_name(self):
#
#         return self.name
#     def del_name(self):
#         del self.name
#
#
# a=Police()
# a.name='蓝雨'
# print('***********')
# #################
# class Police:
#     def __init__(self):
#         self.name='xihuo'
#
#     def __setattr__(self, key, value):
#         if key=='name':
#            self.__dict__[key]=value
#     def get_name(self):
#
#         return self.name
#     def del_name(self):
#         del self.name
#
#
# a=Police()
# a.xihuo='蓝雨'
# print(a.xihuo)


